import React, {useState, useEffect, useCallback, useRef} from 'react';
import {connect} from 'react-redux';
import {withRouter} from 'react-router-dom';

import './index.styl';
import {CaretDownOutlined, CaretUpOutlined, QuestionCircleFilled} from '@ant-design/icons';
import {Icon as LegacyIcon} from '@ant-design/compatible';
import {Button, Spin, Popover, Tabs, message, Table, DatePicker, Empty} from 'antd';
import {
    getAnalysisFeatureDataApi,
    getAnalysisTrendApi,
    getAnalysisTrendDetailApi,
    downloadTrendListApi,
    getAnalysisDistributionDataApi
} from '~/service/performance';
import {MEASURE_TYPE, TIME_DURATION, TARGET_TYPE_ENUM, TARGET_TYPE} from '~/utils/const';
import DateRangeSelector from '../common/DateRangeAndDurationSelector';
import {generateLatestWeek, calcDateRangeStr, dateTransfer, popUpContainer} from '../utils';
import {
    calculateTime,
    analysisDistributeList,
    measureTypeMap,
    columns,
    distributionText,
    defaultFeatureData
} from './data';
import TrendCharts from './trendCharts';
import DistributionCharts from './distributionCharts';
import useDate from './searchForm/FormStore';
import SearchForm from './searchForm';

const {RangePicker} = DatePicker;
const {TabPane} = Tabs;
const {ONE_DAY} = TIME_DURATION;
const {currentTime, circleTime} = calculateTime();
// eslint-disable-next-line max-lines-per-function
function CodePagesAnalysis(props) {
    const {match: {params: {id}}} = props;

    const [state, FormContext, dispatch] = useDate(props);
    const {business, project, path, sortedTargetTypes, clientType} = state;
    const [showLoading, setShowLoading] = useState(false);
    const [showTrendChartsLoading, setShowTrendChartsLoading] = useState(false);
    const [showDistributionChartsLoading, setShowDistributionChartsLoading] = useState(false);
    const [featureData, setFeatureData] = useState(defaultFeatureData);

    // charts tab
    const [chartsTab, setChartsTab] = useState(3);
    const distributionTab = useRef(1);
    // 页面趋势数据
    const [trendData, setTrendData] = useState();
    // 性能分布数据
    const [distributionData, setDistributionData] = useState();
    const [distributionDateRange, setDistributionDateRange] = useState(generateLatestWeek());
    // 页面趋势日期选择
    const [duration, setDuration] = useState(ONE_DAY);
    const [dateRange, setDateRange] = useState(generateLatestWeek());
    // 展开页面数据
    const [expand, setExpand] = useState(false);
    const [dataSource, setDataSource] = useState([]);
    const [pagination, setpPagination] = useState({
        pageSize: 10,
        pageNum: 1,
        total: 0,
        current: 1,
        showSizeChanger: true,
        size: 'default',
        pageSizeOptions: ['10', '20', '50', '100']
    });

    // 三期需求，需要点击搜索按钮后，才触发修改时刷新
    const [searched, setSearched] = useState(false);

    // 获取页面性能趋势数据列表
    const getAnalysisTrend = async measureType => {
        if (business && project && path) {
            setShowTrendChartsLoading(true);
            const [startTime, endTime] = calcDateRangeStr(dateRange);
            const data = {
                bizTypeName: business,
                bizName: project,
                path,
                startTime,
                endTime,
                timeType: duration,
                clientType,
                measureType: measureType ? measureType : chartsTab
            };
            // 如果宿主环境是全部，则不能传递此参数
            if (clientType === 0) {
                delete data.clientType;
            }
            const res = await getAnalysisTrendApi(data);
            setShowTrendChartsLoading(false);
            if (res.code === 0) {
                setTrendData(res.data.measureValues);
            }
            else {
                message.error(res.msg);
            }
        }
    };
    // 页面趋势日期选择时
    const updateTimeInfo = useCallback(({dateRange, duration}) => {
        if (dateRange) {
            setDateRange(dateRange);
        }
        if (duration) {
            setDuration(duration);
        }
    }, []);
    // 获取性能分布数据
    const getAnalysisDistributionData = async value => {
        if (business && project && path) {
            setShowDistributionChartsLoading(true);
            const [startTime, endTime] = calcDateRangeStr(distributionDateRange);
            const data = {
                targetType: value ? value : distributionTab.current,
                bizTypeName: business,
                bizName: project,
                path,
                startTime,
                endTime,
                field: 'client_type',
                // 分端分布
                fieldValue: clientType,
                pageId: id
            };
            if (distributionTab.current === 3 && clientType === 0) {
                delete data.field;
                delete data.fieldValue;
            }
            else if (clientType === 0) {
                delete data.fieldValue;
            }
            const res = await getAnalysisDistributionDataApi(data);
            setShowDistributionChartsLoading(false);
            if (res === null) {
                return;
            }
            setDistributionData(res.data.distributions);
        }
    };
    // 获取页面趋势列表
    const getAnalysisTrendDetail = async paginationData => {
        if (business && project && path) {
            setShowLoading(true);
            const [startTime, endTime] = calcDateRangeStr(dateRange);
            const param = {
                bizTypeName: business,
                bizName: project,
                path,
                startTime,
                endTime,
                timeType: duration,
                clientType,
                pager: {
                    pageSize: paginationData ? paginationData.pageSize : 10,
                    pageNum: paginationData ? paginationData.current : 1
                }
            };
            // 如果宿主环境是全部，则不能传递此参数
            if (clientType === 0) {
                delete param.clientType;
            }
            const res = await getAnalysisTrendDetailApi(param);
            if (res === null) {
                setShowLoading(false);
                return;
            }
            const data = res.data.details.map((item, index) => ({
                ...item,
                datetime: dateTransfer(item.datetime, duration),
                key: `key${index}`
            }));
            setpPagination({
                ...pagination,
                pageSize: res.pager.pageSize,
                pageNum: data.length === 0 ? 1 : res.pager.pageNum,
                total: data.length === 0 ? 0 : res.pager.count,
                current: data.length === 0 ? 1 : res.pager.pageNum,
            });
            setDataSource(data);
            setShowLoading(false);
        }
    };
    const changePage = useCallback(paginationData => {
        getAnalysisTrendDetail(paginationData);
    });
    // 页面趋势时间范围改变时，需要改变
    useEffect(() => {
        if (searched) {
            getAnalysisTrend();
            if (expand) {
                getAnalysisTrendDetail();
            }
        }
    }, [duration, dateRange]);
    // 设置指标tab展示状态
    const [analysisDistributeListShow, setAnalysisDistributeListShow] = useState(analysisDistributeList);

    // 获取环周比数据
    const getAnalysisFeatureData = () => {
        setShowLoading(true);
        Promise.all(MEASURE_TYPE.map(item => {
            const param = {
                targetType: sortedTargetTypes[0],
                bizTypeName: business,
                bizName: project,
                clientType,
                path,
                measureType: item.value
            };

            // 如果宿主环境是全部，则不能传递此参数
            if (clientType === 0) {
                delete param.clientType;
            }
            return getAnalysisFeatureDataApi(param);
        })).then(res => {
            if (res === null || res.code === 1) {
                setShowLoading(false);
                return;
            }
            const list = [];
            res.forEach((item, index) => {
                let flag = '';
                if (item.data.featurePanel.wowRatio !== null) {
                    if (item.data.featurePanel.wowRatio === 0.00) {
                        flag = '不变';
                    }
                    else if (item.data.featurePanel.wowRatio > 0) {
                        flag = '增长';
                    }
                    else if (item.data.featurePanel.wowRatio < 0) {
                        flag = '下降';
                    }
                }
                list.push({
                    ...item.data.featurePanel,
                    key: `本周${TARGET_TYPE.get(sortedTargetTypes[0])}-${MEASURE_TYPE[index].label}`,
                    currentTime,
                    circleTime,
                    detail: measureTypeMap.get(index + 1).detail,
                    flag
                });
            });
            setFeatureData(list);
            setShowLoading(false);
        });
    };
    // change 性能趋势tab
    const changeChartsTab = useCallback(value => {
        value = Number(value);
        setChartsTab(value);
        getAnalysisTrend(value);
    });
    // change 性能分布tab
    const changeDistributionTab = useCallback(value => {
        value = Number(value);
        distributionTab.current = value;
        getAnalysisDistributionData(value);
    });
    // 搜索
    const searchBtn = useCallback(() => {
        if (business && project && path) {
            setSearched(true);
            getAnalysisTrend();
            getAnalysisFeatureData();
            getAnalysisDistributionData();
            if (expand) {
                getAnalysisTrendDetail();
            }
        }
    });
    // 展开明细数据
    const changeExpand = useCallback(() => {
        setExpand(!expand);
        if (!expand) {
            getAnalysisTrendDetail();
        }
    });
    // 下载明细数据
    const downloadDataList = useCallback(async () => {
        if (business && project && path) {
            const [startTime, endTime] = calcDateRangeStr(dateRange);
            setShowLoading(true);
            const param = {
                bizTypeName: business,
                bizName: project,
                path,
                clientType,
                startTime,
                endTime,
                timeType: duration
            };
            // 如果宿主环境是全部，则不能传递此参数
            if (clientType === 0) {
                delete param.clientType;
            }

            await downloadTrendListApi(param);
            setShowLoading(false);
        }
        else {
            message.warn('请选择查询条件');
        }
    });
    const resetFun = useCallback(() => {
        setFeatureData(defaultFeatureData);
        setChartsTab(3);
        changeDistributionTab(1);
        setTrendData([]);
        setDistributionData([]);
        setExpand(false);
        setDataSource([]);
        setDuration(ONE_DAY);
        setDateRange(generateLatestWeek());
        setDistributionDateRange(generateLatestWeek());
        setAnalysisDistributeListShow(analysisDistributeList);
    });

    useEffect(() => {
        if (searched) {
            getAnalysisDistributionData();
        }
    }, [distributionDateRange]);

    useEffect(() => {
        // 当所选路径包含这几个指标时，显示分端分布
        const newList = [...analysisDistributeList];
        if (sortedTargetTypes.includes(TARGET_TYPE_ENUM.FIP)) {
            newList.unshift({value: TARGET_TYPE_ENUM.FIP, label: TARGET_TYPE.get(TARGET_TYPE_ENUM.FIP)});
        }

        if (sortedTargetTypes.includes(TARGET_TYPE_ENUM.FR)) {
            newList.unshift({value: TARGET_TYPE_ENUM.FR, label: TARGET_TYPE.get(TARGET_TYPE_ENUM.FR)});
        }

        if (sortedTargetTypes.includes(TARGET_TYPE_ENUM.FI)) {
            newList.unshift({value: TARGET_TYPE_ENUM.FI, label: TARGET_TYPE.get(TARGET_TYPE_ENUM.FI)});
        }

        if (sortedTargetTypes.includes(TARGET_TYPE_ENUM.FSP)) {
            newList.unshift({value: TARGET_TYPE_ENUM.FSP, label: TARGET_TYPE.get(TARGET_TYPE_ENUM.FSP)});
        }

        if (sortedTargetTypes.includes(TARGET_TYPE_ENUM.TTDC)) {
            newList.unshift({value: TARGET_TYPE_ENUM.TTDC, label: TARGET_TYPE.get(TARGET_TYPE_ENUM.TTDC)});
        }

        setAnalysisDistributeListShow(newList);

        if (sortedTargetTypes.length > 0) {
            distributionTab.current = sortedTargetTypes[0];
        }
    }, [sortedTargetTypes]);
    return (
        <FormContext.Provider value={{
            state,
            dispatch
        }}
        >
            <Spin spinning={showLoading}>
                <div className="code-page-analysis-container">
                    <div className="code-page-analysis-header">
                        <div className="info-section">
                            <span className="title">性能总体特征</span>
                        </div>
                        <hr className="line" />
                        <div className="search-container">
                            <SearchForm submit={searchBtn} resetFun={resetFun} />
                        </div>
                    </div>
                    <div className="analysis-feature">
                        {
                            featureData && featureData.map(item => (
                                <div
                                    key={item.key}
                                    className={`feature-item ${item.flag === '增长' ? 'border-arrow-up' : ''}
                                        ${item.flag === '下降' ? 'border-arrow-down' : ''}`
                                    }
                                >
                                    <h5>
                                        {item.key}
                                        <Popover content={item.detail} overlayClassName="analysisPopover">
                                            <QuestionCircleFilled />
                                        </Popover>
                                        <span className="pv">
                                            pv:
                                            {item.pv !== -1 && item.pv}
                                        </span>
                                    </h5>
                                    <span className="font-12">
                                        {item.currentTime.replace(/\//g, '-')}
                                        |更新时间 T + 1
                                    </span>
                                    <div className="text-center">
                                        <h2 >
                                            {item.value ? `${item.value}` : '-'}
                                        </h2>
                                        {item.value ? <h3>ms</h3> : ''}
                                    </div>
                                    <div className="text-center">
                                        <Popover
                                            content={
                                                `对比上周${item.circleTime.replace(/\//g, '-')}
                                                ${item.flag}
                                                ${item.wowRatio ? `${Math.abs(item.wowRatio)}%`
                                    : (item.wowRatio === 0.00 ? '' : '-')}`
                                            }
                                        >
                                            周环比:
                                            <span className="upOrdownfont">
                                                {item.wowRatio ? ` ${Math.abs(item.wowRatio)} %`
                                                    : (item.wowRatio === 0.00 ? '0.00' : '-')}
                                            </span>
                                            {item.flag === '增长' && (<CaretUpOutlined />)}
                                            {item.flag === '下降' && (<CaretDownOutlined />)}
                                        </Popover>
                                    </div>
                                </div>
                            ))
                        }
                    </div>
                    <div className="analysis-charts-body">
                        <div className="info-section">
                            <span className="title">页面性能趋势</span>
                        </div>
                        <Tabs onChange={changeChartsTab} defaultActiveKey={chartsTab.toString()}>
                            {
                                MEASURE_TYPE.map(item => (
                                    <TabPane tab={item.label} key={item.value} />
                                ))
                            }
                        </Tabs>
                        <DateRangeSelector
                            duration={duration}
                            dateRange={dateRange}
                            setDateRangeAndDuration={updateTimeInfo}
                            getCalendarContainer={popUpContainer}
                        />
                        {
                            trendData && trendData.length ? (
                                <TrendCharts
                                    data={trendData}
                                    loading={showTrendChartsLoading}
                                    duration={duration}
                                    sortedTargetTypes={sortedTargetTypes}
                                />
                            ) : <Empty imageStyle={{height: 70}} image={Empty.PRESENTED_IMAGE_SIMPLE} />
                        }
                        <div className="chart-option">
                            <div className="expand-btn" onClick={changeExpand}>
                                {
                                    expand ? '收起明细数据' : '展开明细数据'
                                }
                                <LegacyIcon type={expand ? 'up' : 'down'} />
                            </div>
                            <div className="float-r">
                                <Button type="primary" onClick={downloadDataList}>下载</Button>
                            </div>
                        </div>
                        {
                            expand && (
                                <Table
                                    size="small"
                                    columns={columns}
                                    dataSource={dataSource}
                                    pagination={pagination}
                                    onChange={changePage}
                                    loading={showLoading}
                                />
                            )
                        }
                    </div>
                    <div className="analysis-distribute">
                        <div className="info-section">
                            <span className="title">性能分布</span>
                            <Popover content={distributionText}>
                                <QuestionCircleFilled />
                            </Popover>
                        </div>
                        <div className="m-5">
                            <span>日期</span>
                            <RangePicker
                                allowClear={false}
                                className="duration-selector"
                                defaultValue={distributionDateRange}
                                onChange={setDistributionDateRange}
                                getCalendarContainer={popUpContainer}
                            />
                        </div>
                        <Tabs
                            onChange={changeDistributionTab}
                            activeKey={distributionTab.current.toString()}
                        >
                            {
                                analysisDistributeListShow.map(item => (
                                    <TabPane tab={item.label} key={item.value} />
                                ))
                            }
                        </Tabs>
                        {
                            distributionData && distributionData.length ? (
                                <DistributionCharts
                                    data={distributionData}
                                    targetType={distributionTab}
                                    loading={showDistributionChartsLoading}
                                    clientType={clientType}
                                />
                            ) : <Empty imageStyle={{height: 70}} image={Empty.PRESENTED_IMAGE_SIMPLE} />
                        }
                    </div>
                </div>
            </Spin>
        </FormContext.Provider>
    );
}

export default connect(s => s)(withRouter(CodePagesAnalysis));
